/*
    DIMVisual, the Data Integration Model for Visualization of trace files.
    Copyright (c) 2008 Lucas Mello Schnorr <schnorr@gmail.com>

    This file is part of DIMVisual.

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
#include "Ordering.h"

@implementation Ordering

- (id) init
{
        self = [super init];
        sources = [[NSMutableArray alloc] init];
        return self;
}

- (void) dealloc
{
	[sources release];
	[super dealloc];
}

- (void) up: (int) kid
{
        int father;

        if (kid%2 == 0){
                father = kid/2 - 1;
        }else{
                father = kid/2;
        }
        if (father >= 0){
                if ([[[sources objectAtIndex: kid] time] doubleValue] <
                   [[[sources objectAtIndex: father] time] doubleValue]){
                        [sources exchangeObjectAtIndex: kid withObjectAtIndex: father];
                        [self up: father];
                }
        }
}

- (void) down: (int) father : (int) n
{
        int kid;

        kid = father*2 + 1;
        if (n == 1){
                return;
        }
        if (kid < n){
                if (kid <= (n-2)){
                        double dkidOneMore = [[[sources objectAtIndex: kid+1] time] doubleValue];
                        double dkid = [[[sources objectAtIndex: kid] time] doubleValue];
                        if (dkidOneMore < dkid){
                                kid = kid + 1;
                        }
                }
                if ([[[sources objectAtIndex: father] time] doubleValue] >
                    [[[sources objectAtIndex: kid] time] doubleValue]){
                        [sources exchangeObjectAtIndex: father withObjectAtIndex: kid];
                        [self down: kid: n];
                }
        }
}

- (id<FileReader>) remove
{
        id<FileReader,NSObject> ret;
        ret = [sources objectAtIndex: 0];
        if (ret == nil){
                return nil;
        }
        [ret retain];
        if ([sources count] > 1){
                [sources exchangeObjectAtIndex: 0 withObjectAtIndex: [sources count] - 1];
        }
        [sources removeObjectAtIndex: [sources count] - 1];
        [self down: 0: [sources count]];
        [ret autorelease];
        return ret;
}

- (void) add: (id<Time>) source
{
        [sources addObject: source];
        //[self up: [sources count] - 1];
}


- (id<Time>) mostRecent
{
	if ([sources count] == 0){
		return nil;
	}
	NSArray *ret;
	ret = [sources sortedArrayUsingSelector: @selector(compareTime:)];
	return [ret objectAtIndex: 0];
	//END HERE

	int i;
	int trocou;

	if ([sources count] == 0){
		return nil;
	}
	if ([[sources objectAtIndex: 0] time] == nil){
		[sources removeObjectAtIndex: 0];
		if ([sources count] == 0){
			return nil;
		}

	}

	trocou = 1;
	while (trocou){
		trocou = 0;
		for (i = 0; i < [sources count]; i++){
		    if (i+1 < [sources count]){
			if ([[[sources objectAtIndex: i] time] doubleValue] >
        	            [[[sources objectAtIndex: i+1] time] doubleValue]){
				[sources exchangeObjectAtIndex: i withObjectAtIndex: i+1];
				trocou = 1;
        	        }
		    }
		}
	}
	return [sources objectAtIndex: 0];

/*

	id ds;
        while ([sources count] > 0){
                ds = [self remove];
                [ds retain];
                if ([ds time] != nil){
                        [self add: ds];
		}
                [ds autorelease];
                return ds;
        }
        return nil;
*/
}

@end
